home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-02-03 | 106.1 KB | 2,341 lines |
- ; ***********************************************************************
- ; * *
- ; * *
- ; * ***** ***** *
- ; * ***** ***** *
- ; * ***** ***** *
- ; * ***** ***** *
- ; * *************** *************** *
- ; * ***************** ***************** *
- ; * *************** *************** *
- ; * ***** ***** The Net. *
- ; * ***** ***** Portable. Compatible. *
- ; * ***** ***** Public Domain. *
- ; * ***** ***** By NORD><LINK. *
- ; * *
- ; * *
- ; * *
- ; * TNL1.MAC - Z80 Level 1, Hardwareanpassungen, Interrupts *
- ; * *
- ; * angelegt: DC4OX *
- ; * modifiziert: *
- ; * *
- ; ***********************************************************************
-
- ; modifications by G8KBB
- ;
- ; 1 put .z80 mode on
- ; 2 change definitions of variables to 'global' so they go into
- ; uninitialised space not into rom data segment
- ; 3 define .begin to fool the compiler
- ; 4 change definition of minmem() so that it reads from Fremem
- ; an address written by the linker rather than using the address
- ; of fremem, where it is the last variable in udata.
- ; 5 clean up definitions for case sensitivity in many cases
- ; 6 alter STAled & CONled to use decEI & DIinc functions
- ; 7 Add additional default definitions for extended operation
- ; 8 Add KISS code to crosslink driver
- ; 9 Add code for host mode operation
- ; Change stack initialisation in L1INIT
- ; Incorporate DF2AU HDLC IRQ lockup bug
- ; Add stats gathering for L1 bits
- ; Comment out the STAled & CONled routines
- ; Factor out raise_dcd_ as a function from CTXINI
- ; Add devmeter support to SIASRC
- ; use ex & exx instead of lods of push / pops
- ; add a small reset delay to L1INIT
-
- ; released as thenet x-1j september 1993
-
- .z80
-
- ;
- ; Achtung : Hier wird mit "Crosslink" ausschliesslich die Verbindung
- ; zweier TNC's ueber die RS232-Schnittstelle bezeichnet.
- ; Somit wird der RS232-Kanal zwischen 2 TNC's als
- ; "Crosslink-Kanal" bezeichnet, der Modem-Kanal als
- ; "HDLC-Kanal".
- ;
-
-
-
-
-
- ; =======================================================================
- ;
- ; Equates
- ;
- ; =======================================================================
-
-
-
- ;
- ; benutzte "Magic Number" zum RAM-Test Warmstart/Kaltstart
- ;
- MAGIC equ 4D5Ah
-
-
-
- ;
- ; Hardware-I/O-Ports
-
- SIADAT equ 0 ; SIO Kanal A (HDLC) Data
- SIACTL equ 1 ; SIO Kanal A (HDLC) Control
- SIBDAT equ 2 ; SIO Kanal B (RS232) Data
- SIBCTL equ 3 ; SIO Kanal B (RS232) Control
-
- ADC equ 32 ; adc i/o port
- ADC_CH1 equ 4 ; command to convert port 1 data
- ADC_CH2 equ 5 ; command to convert port 2 data
-
- ;
- ; niedrigste RAM-Speicherstelle
- ;
- RAMBOT equ 8000h
-
-
-
- ;
- ; ASCII-Kontrollzeichen
- ;
- ASTX equ 02h ; ASCII Start of Text = Control B
- AETX equ 03h ; ASCII End of Text = Control C
- ADLE equ 10h ; ASCII Data Link Escape = Control P
- ACAN equ 18h ; ASCII Cancel = Control X
- AESC equ 1Bh ; ASCII Escape
-
- FEND equ 0c0h ; KISS frame start / end
- FESC equ 0dbh ; KISS frame escape
- TFEND equ 0dch ; KISS frame start / end shift char
- TFESC equ 0ddh ; KISS frame escape shift char
-
-
-
- ;
- ; Hostterminal FIFO-Groessen
- ;
- HORXFL equ 256 ; RX FIFO Laenge
- HOTXFL equ 256 ; TX FIFO Laenge
-
-
-
-
-
- ; =======================================================================
- ;
- ; Arbeitsspeicher
- ;
- ; =======================================================================
-
- ; dseg
-
- global RAMVEC,16
- ;RAMVEC: ds 16 ; Interrupt Vektor im RAM
-
- ;
- ; Hostkanal, SIO Kanal B, RS232-Schnittstelle,
- ; wenn Hostterminal angeschlossen
- ;
- ;HORXCC: ds 2 ; RX "character count" Anzahl Zeichen
- ;HORXFI: ds HORXFL ; RX "fifo" FIFO-Ringspeicher
- ;HORXIP: ds 2 ; RX "input pointer" Eingangszeiger
- ;HORXOP: ds 2 ; RX "output pointer" Ausgangszeiger
- ;HOTXCC: ds 2 ; TX "character count" Anzahl Zeichen
- ;HOTXFI: ds HOTXFL ; TX "fifo" FIFO-Ringspeicher
- ;HOTXIP: ds 2 ; TX "input pointer" Eingangszeiger
- ;HOTXOP: ds 2 ; TX "output pointer" Ausgangszeiger
- global HORXCC,2
- global HORXFI,HORXFL
- global HORXIP,2
- global HORXOP,2
- global HOTXCC,2
- global HOTXFI,HOTXFL
- global HOTXIP,2
- global HOTXOP,2
-
- ;
- ; SIO Kanal B, RS232-Schnittstelle
- ;
- ;SIBWR5: ds 1 ; Sicherung WR5, Tx-Modus
- ;SIBRR0: ds 1 ; Sicherung RR0, Status
- global SIBWR5,1
- global SIBRR0_,1
-
- ;
- ; Crosslink, SIO Kanal B, RS232-Schnittstelle,
- ; wenn TNC im Crosslink betrieben
- ;
- ;CRXSTA: ds 1 ; RX "state"
- ; 0 - RX inaktiv
- ; 1 - RX aktiv, innerhalb Frame
- ; 2 - RX aktiv, letztes Zeichen war DLE, naechstes
- ; wird nicht interpretiert (STX/ETX/DLE)
- ; 3 - Frameende, naechstes Zeichen ist Checksum
- ; 4 - KISS ignore command byte
- ;CRXFCS: ds 1 ; RX "frame checksum" (8 Bit, Summe modulo 256)
- ;CTXSTA: ds 1 ; TX "state"
- ; 0 - TX inaktiv
- ; 1 - nachdem Port frei wird (DTR high)
- ; (ASync-)WAIT-Sendesequenz eineiten
- ; 2 - nachdem Port frei wird (DTR high)
- ; Nicht-(Async-)WAIT-Sendesequenz einleiten
- ; 3 - (Async-)WAIT abwarten
- ; 4 - Vorlauftraeger (CTS low) gesetzt,
- ; 2,5 msec warten
- ; 5 - TX aktiv, innerhalb Frame
- ; (vor ETX/Checksumme)
- ; 6 - TX aktiv, Frameende, ETX gesendet,
- ; weitere Frames vorhanden
- ; 7 - TX aktiv, Frameende, ETX gesendet,
- ; keine weiteren Frames vorhanden
- ; 8 - TX aktiv, Frameende, Checksumme gesendet,
- ; weitere Frames vorhanden
- ; 9 - TX aktiv, Frameende, Checksumme gesendet,
- ; keine weiteren Frames vorhanden
- ; 10 - wie 9, vorletztes Zeichen aus internem
- ; SIO-FIFO gesendet
- ; 11 - wie 9, letztes Zeichen aus internem
- ; SIO-FIFO gesendet
- ; 12 - KISS frame start
- ;CTXFCS: ds 1 ; TX "frame checksum" (8 Bit, Summe modulo 256)
- ;CTXCSA: ds 1 ; TX "character save" fuer Zeichen mit DLE-Vorlauf
- global CRXSTA,1
- global CRXFCS,1
- global CTXSTA,1
- global CTXFCS,1
- global CTXCSA,1
-
- ;
- ; HDLC-Kanal, SIO Kanal A, PR-Modemschnittstelle
- ;
- ;SIAWR5: ds 1 ; Sicherung WR5, Tx-Modus
- ;SIARR0: ds 1 ; Sicherung RR0, Status
- ;HRXSTA: ds 1 ; RX "state"
- ; 0 - RX ausserhalb Frame
- ; 1 - RX innerhalb Frame
- ;HRXLCH: ds 1 ; RX "last character" 1-Zeichen-FIFO, Zeichen erst
- ; gueltig, wenn Nicht-Frameende-Status von SIO
- ;HTXSTA: ds 1 ; TX "state"
- ; 0 - TX inaktiv
- ; 1 - nachdem Port frei wird (DCD low)
- ; WAIT-Sendesequenz einleiten
- ; 2 - nachdem Port frei wird (DCD low)
- ; Nicht-WAIT-Sendesequenz einleiten
- ; 3 - WAIT warten
- ; 4 - TX aktiv, PTT, TXDELAY abwarten
- ; 5 - TX aktiv, innerhalb Frame Datenbytes
- ; 6 - TX aktiv, letztes Datenbyte fuer Frame
- ; gesendet, weitere Frames vorhanden
- ; 7 - TX aktiv, letztes Datenbyte fuer Frame
- ; gesendet, keine weiteren Frames vorhanden
- ; (mit 6 oder 7 laeuft TX in den TX-Underrun/
- ; EoM-Interrupt, naechster TX-Buffer-Empty-
- ; Interrupt : 1. CRC-Byte hat SIO verlassen)
- ; 8 - TX aktiv, CRC verlaesst SIO
- ; 9 - TX aktiv, Frameendeflag verlaesst SIO
- ; 10 - TX aktiv, Frameendeflag hat SIO komplett
- ; verlassen
- global SIAWR5,1
- global SIARR0,1
- global HRXSTA,1
- global HRXLCH,1
- global HTXSTA,1
-
- ;
- ; Zaehler
- ;
- ;TICDIV: ds 1 ; Zaehler bis 12, 1200Hz Interrupts -> 10msec
- ;HTXWAI: ds 1 ; 10msec HDLC-TX-Wartezaehler (WAIT/TXDELAY)
- ;CTXWAI: ds 1 ; 1200Hz Crosslink-TX-Wartezaehler (Async-WAIT)
- global TICDIV,1
- global HTXWAI,1
- global CTXWAI,1
-
- ;
- ; Sonstiges
- ;
- ;DEICNT: ds 1 ; Interrupt Verbietungsstufe
- ;RAMTOP: ds 2 ; oberste verfuegbare RAM-Speicherstelle
- ;URAND: ds 2 ; (fuer random(), damit Gleichverteilung)
- global DEICNT,1
- global RAMTOP,2
- global URAND,2
-
- ;sig_level: ds 1 ; temp store for smeter reading
- global sig_level_,1
-
- ; =======================================================================
- ;
- ; Code
- ;
- ; =======================================================================
-
- cseg
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | Reset-Einsprungsvektor, RST-Vektoren. |
- ; | |
- ; +---------------------------------------------------------------------+
-
-
- public reset_, .begin
-
- public .eq, .ne, .ug, .an, .sb
-
- .begin equ $
- reset_: jp L1INIT ; Resetvektor
-
- db 0,0,0,0,0
- ;
- ; Runtime speedup & code size. These are all runtine functions
- ; removed from the file SUPPORT.MAC. They have been replaced by
- ; RST as RST is shorter and quicker than CALL. These are the
- ; most frequently used functions. The remainder of SUPPORT.MAC
- ; has been appended to CRUN.MAC
- ;
- ; RST 8 .an ; return HL = HL & DE
- ;
- .an: ld A,H
- and D
- ld H,A
- ld A,L
- and E
- ld L,A
- or h
- ret
- ;
- ; RST 10 .ne
- ;
- .ne: xor a
- sbc hl,de
- jr z,.false
- .true: ld hl,1
- ld a,l
- or h
- ret
-
- db 0,0,0,0,0
- ;
- ; RST 18 unusable as RST 10 is too long
- ;
- ; RST 20 .ug
- ;
- .ug: xor a
- sbc hl,de
- jr c,.true
- jr .false
-
- db 0
-
- ;
- ; RST 28 .sb
- ;
- .sb: ex de,hl
- or a
- sbc hl,de
- ret
-
- db 0,0,0
-
- ;
- ; RST 30 .eq
- ;
- .eq: xor a
- sbc hl,de
- jr z,.true
- .false: xor a ; Clear carry (and A)
- ld h,a ; Set HL = 0;
- ld l,a
- ret
-
- db 0,0
-
- ;
- ; RST 38 unusable
- ;
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | Default-Parameter. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public DEFCAL_, DEFIDE_, DEFDES_, DEFWQU_, DEFCH0_, DEFCH1_
- public DEFOBC_, DEFOBB_, DEFBRI_, DEFTLI_, DEFTTO_, DEFTTR_
- public DEFTAC_, DEFTBS_, DEFTWI_, DEFCON_, DEFNOA_, DEFPER_
- public DEFSLO_, DEFRAK_, DEFMAF_, DEFL2T_, DEFLT2_, DEFLT3_
- public DEFRPA_, DEFVAL_, DEFBEA_, DEFCQ_, DEFDPA_, DEFXFP_
- public DEFESC_, DEFTP_, DEFPWD_, DEFINF_
- public DEFCW_, DEFHOS_, DEFKIS_, DEFCWS_, DEFMHL_
- public beadil_, DEFBCN_, DEFBR1_, DEFALG_, DEFCSB_, DEFBIN_
- public DEFNOHASH_, DEFMYIPADDR_, DEFIPBCAST_, DEFIPL2MODES_
- public DEFIPTTL_, DEFIPENABLE_, DEFHLP_
- public DEF_MTU_I_MAX_, DEF_MTU_L2_MAX_
- public DEF_MTU_IP0_, DEF_MTU_IP1_, DEF_MTU_IPN_
- public DEFRECONNECT_, DEFNO_SLIME_, DEFNO_DIGI_, DEFDEVMETER_
- public DEFMETERFLAGS_, DEFRXSIGMIN_, DEFRXSMETER_, DEFRXDB_
- public DEFDBFLOOR_, DEFMULT1_, DEFMULT2_, DEFOFS1_, DEFOFS2_
- public DEFMULT3_, DEFMULT4_, DEFOFS3_, DEFOFS4_
-
- DEFCAL_: db 'G8KBB ', 6Ah ; Call des TNC
- DEFIDE_: db 'THENET' ; Ident des TNC
- DEFDES_: dw 100 ; Laenge der Destination Liste
- DEFWQU_: dw 10 ; minimale Qualitaet fuer Autoupdate
- DEFCH0_: dw 10 ; HDLC Kanal Qualitaet
- DEFCH1_: dw 255 ; RS232 Kanal Qualitaet
- DEFOBC_: dw 7 ; Anfangswert Knotenlebensdauer
- DEFOBB_: dw 5 ; Restlebensdauer fuer Rundspruch
- DEFBRI_: dw 1800 ; Rundspruchintervall
- DEFTLI_: dw 10 ; Anfangswert Paketlebensdauer
- DEFTTO_: dw 300 ; Timeout in Level3
- DEFTTR_: dw 2 ; Versuche in Level3
- DEFTAC_: dw 6 ; Level3 Wartezeit bis ACK
- DEFTBS_: dw 180 ; Level3 Busy Wartezeit
- DEFTWI_: dw 4 ; Fenstergroesse in Level3
- DEFCON_: dw 4 ; gebufferte Frames je Verbindung
- DEFNOA_: dw 900 ; no-activity-timeout
- DEFPER_: dw 64 ; Entschlossenheit fuer Sendung frei
- DEFSLO_: dw 10 ; Zeitschlitzbreite
- DEFRAK_: dw 5 ; Level2, Timer1
- DEFMAF_: dw 2 ; Level2, Fenstergroesse
- DEFL2T_: dw 10 ; Level2, Versuche
- DEFLT2_: dw 100 ; Level2, Timer2
- DEFLT3_: dw 18000 ; Level2, Timer3
- DEFRPA_: dw 0 ; Level2 Digipeating Freigabe
- DEFVAL_: dw 1 ; Calls pruefen
- DEFBEA_: dw 2 ; Bakenmodus
- DEFCQ_: dw 1 ; CQ-Ruf erlaubt j/n
- DEFDPA_: db 0 ; Full-Duplex j/n
- DEFXFP_: db 0 ; Flags in den Pausen
- DEFESC_: db 01Bh ; Befehlseinleitungszeichen (Host)
- DEFTP_: db 30 ; Senderverzoegerung
-
- DEFPWD_: db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 '
- db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 ',0 ; Passwort
-
- DEFINF_: db 'SOFTWARE VON NORD><LINK Modified and ext'
- db 'ended by G8KBB, East Suffolk Data Group ',0 ; Infotext
- ;
- ; Additional defaults for extended versions
- ;
- DEFCW_: dw 1800 ; 0 = off, else period in minutes
- DEFCWS_: db 6 ; bit speed in 10's of milliseconds
- DEFHOS_: db 0 ; 0 = thenet, 1 = host mode
- DEFKIS_: db 0 ; 0 = crosslink, 1 2 or 3 = kiss
- DEFMHL_: db 10 ; 0 = no heard list, else list length
- DEFBCN_: db 3 ; controls which ports for nodes bcst
- DEFBR1_: dw 0 ; interval for port 1 bcasts, 0=off
- DEFALG_: db 0 ; node bcast algorithm selector
- beadil_: db 0,0,0,0,0,0,0,0 ; optional single beacon digilist
- DEFBIN_: dw 900 ; beacon interval in seconds
- DEFCSB_: db 1 ; connect to host(0), BBS(1)
- DEFNOHASH_: db 0 ; per port bit for hash node ctrl
- DEFMYIPADDR_: dw 0,0 ; this node's IP address
- DEFIPBCAST_: dw 0,0 ; the IP broadcast address
- DEFIPL2MODES_: db 0 ; per port IP L2 default modes
- DEFIPTTL_: db 20 ; IP Time To Live
- DEFIPENABLE_: db 1 ; enable / disable IP router
- DEFHLP_: db 31 ; help flags default
- DEF_MTU_IP0_: dw 256 ; ip port 0 mtu
- DEF_MTU_IP1_: dw 256 ; ip port 1 mtu
- DEF_MTU_IPN_: dw 236 ; ip netrom port mtu
- DEF_MTU_I_MAX_: dw 257 ; l2 i frame data max
- DEF_MTU_L2_MAX_: dw 328 ; l2 total frame size max
- DEFRECONNECT_: db 1 ; reconnect on remote disconnect
- DEFNO_SLIME_: db 0 ; slime trail control word
- DEFNO_DIGI_: db 0 ; digipeat control word default
- DEFDEVMETER_: db 0 ; deviation meter control word
- DEFMETERFLAGS_: dw 27 ; meter mode and control flags
- DEFRXSIGMIN_: db 50 ; s meter noise adc reading
- DEFRXSMETER_: db 10 ; s meter multiplier
- DEFRXDB_: db 50 ; dBm multiplier
- DEFDBFLOOR_: db 120 ; dBm noise floor reading
- DEFMULT1_: db 0 ; adc channel 1 multiplier
- DEFMULT2_: db 0 ; adc channel 2 multiplier
- DEFOFS1_: db 0 ; adc channel 1 offset
- DEFOFS2_: db 0 ; adc channel 2 offset
- DEFMULT3_: db 0 ; adc channel 3 multiplier
- DEFMULT4_: db 0 ; adc channel 4 multiplier
- DEFOFS3_: db 0 ; adc channel 3 offset
- DEFOFS4_: db 0 ; adc channel 4 offset
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | SIO (HDLC, RS232) Initialisierungstabellen. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- ;
- ; Mit "Pin" ist immer der SIO-Pin gemeint.
- ; Mit "Modemstecker" ist der RS232-Stecker gemeint - "Modem" in diesem
- ; Zusammenhang bezieht sich auf die Signalbezeichung, der TNC wird ja
- ; bei Anschluss an einen Rechner oder an ein Terminal als "Modem"
- ; betrieben.
- ;
-
-
-
- ;
- ; SIO Kanal B, RS232 (Hostterminal oder Crosslink)
- ;
- SIBINI: db 018h ; WR 0 : Channel Reset
- db 2 ; WR 2 :
- db 000h ; Interrupt Vector (Page-Anfang)
- db 4 ; WR 4 :
- db 044h ; /16 Clock, 1 Stopbit, kein Parity
- db 5 ; WR 5 :
- SIBIW5: db 0EAh ; Tx 8 Bit, Tx Enable, Pin /DTR low,
- ; Pin /RTS low -> Modemstecker CTS high
- db 3 ; WR 3 :
- db 0C1h ; Rx 8 Bit, Rx Enable
- db 1 ; WR 1 :
- db 01Fh ; Interrupt on all Rx Character, Status
- ; affects Vector, Tx Interrupt Enable,
- ; External/Status Interrupt Enable
- db 010h ; WR 0 : Reset External/Status Interrupts
- SIBIEN:
-
-
- public SIAINI, SIAIEN, SIAIW5, SIBIW5
- ;
- ; SIO Kanal A, HDLC (Packet-Radio-Modem)
- ;
- SIAINI: db 018h ; WR 0 : Channel Reset
- db 4 ; WR 4 :
- db 020h ; /1 Clock, SDLC Mode (01111110 Flag),
- ; Sync Modes Enable
- db 5 ; WR 5 :
- SIAIW5: db 0E1h ; Tx 8 Bit, CCITT CRC, Tx CRC Enable,
- ; Pin /DTR low, Pin /RTS high -> PTT aus
- db 3 ; WR 3 :
- SIAIW3: db 0D9h ; Rx 8 Bit, Hunt Phase, Rx CRC Enable,
- ; Rx Enable
- db 7 ; WR 7 :
- db 07Eh ; 01111110 Flag
- db 1 ; WR 1 :
- db 01Bh ; Interrupt on all Rx Character,
- ; Tx Interrupt Enable,
- ; External/Status Interrupt Enable
- db 010h ; WR 0 : Reset External/Status Interrupts
- SIAIEN:
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | Interrupt-Vektor-Tabelle (wird ins RAM uebertragen). |
- ; | |
- ; +---------------------------------------------------------------------+
-
- ROMVEC: dw SIBTBE ; SIO B (RS232) Tx Buffer Empty
- dw SIBESC ; SIO B (RS232) External/Status Change
- dw SIBRCA ; SIO B (RS232) Rx Character Available
- dw SIBSRC ; SIO B (RS232) Special Receive Condition
- dw SIATBE ; SIO A (HDLC) Tx Buffer Empty
- dw SIAESC ; SIO A (HDLC) External/Status Change
- dw SIARCA ; SIO A (HDLC) Rx Character Available
- dw SIASRC ; SIO A (HDLC) Special Receive Condition
- ROMVEN:
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | Level 1 Initialisierung nach einem Reset. |
- ; | |
- ; | - Kaltstart : Speicherausbau feststellen |
- ; | - Stack setzen |
- ; | - SIO initialisieren |
- ; | - Level 1 Variable setzen |
- ; | - Interrupts initialisieren |
- ; | - Interrupts erlauben |
- ; | - Sprung ins Hauptprogramm |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn mainf_ ; C Hauptprogramm
- extrn magicn_ ; im Hauptprogramm definierte Variable
- ; extrn stack_ ; Stack im Hauptprogramm definiert
- extrn stkend_ ; pointer to top of stack (G8KBB)
- extrn l2stats_ ; pointer to l2 stats array ( G8KBB )
-
- L1INIT: di ; Interrupts verbieten fuer Initialisierung
-
- xor A
- l1delay: dec A
- jr nz, l1delay
-
- ld HL,(magicn_) ; RAM ok = Warmstart, d.h.
- ld DE,MAGIC ; Magic Number noch
- or A ; unveraendert,
- sbc HL,DE ; wie ins RAM geschrieben ?
- jr Z,L1INI2 ; ja - RAM-Bestueckung nicht testen
-
- ld HL,RAMBOT+3FFFh ; nein - Ende RAM bei 16kB
- ld DE,RAMBOT+7FFFh ; Ende RAM bei 32kB
- xor A ; 0
- ld (HL),A ; in beide moegliche
- ld (DE),A ; RAM-Enden
- dec (HL) ; oberes RAM-Ende = 0FFh
- ld A,(DE) ; hat sich unteres RAM-Ende geaendert ?
- or A ; (16kB-Bestueckung -> Spiegelung)
- jr NZ,L1INI1 ; ja - es sind nur 16kB
- inc A ; A = 1
- ld (DE),A ; an unteres RAM-Ende
- inc (HL) ; 0 an oberes RAM-Ende, auch gespiegelt ?
- jr NZ,L1INI1 ; ja - andere Hardware, aber auch nur 16kB
- ex DE,HL ; nein - 32kB RAM
- L1INI1: ld (RAMTOP),HL ; oberste RAM-Speicherstelle merken
-
- L1INI2: ld SP,(stkend_)
- ; ld SP,stack_+1 ; Stack setzen
-
- im 2 ; Interruptmode 2 = Vektorinterrupts
- ld A,RAMBOT>>8 ; Interrupt Vektor Page = RAM Anfang
- ld I,A
- ld HL,ROMVEC ; Interrupt-Vektor vom ROM
- ld DE,RAMVEC ; ins RAM
- ld BC,ROMVEN-ROMVEC ; laden
- ldir
-
- ld HL,SIBINI ; SIO B (RS232) initialisieren
- ld BC,SIBCTL or ((SIBIEN-SIBINI)<<8)
- otir
- in A,(SIBCTL) ; SIO B initialen Status holen
- ld (SIBRR0_),A ; und merken
- ld A,(SIBIW5) ; SIO B initialen Tx-Modus holen
- ld (SIBWR5),A ; und merken
-
- ld HL,SIAINI ; SIO A (HDLC) initialisieren
- ld BC,SIACTL or ((SIAIEN-SIAINI)<<8)
- otir
- in A,(SIACTL) ; SIO A initialen Status holen
- ld (SIARR0),A ; und merken
- ld A,(SIAIW5) ; SIO A initialen Tx-Modus holen
- ld (SIAWR5),A ; und merken
-
- call HOINIT ; Host-FiFo's initialisieren
- xor A ; A = 0
- ld (CRXSTA),A ; Crosslink RX inaktiv
- ld (CTXSTA),A ; Crosslink TX inaktiv
- ld (HRXSTA),A ; HDLC RX ausserhalb Frame
- ld (HTXSTA),A ; HDLC TX inaktiv
- ld (TICDIV),A ; 1200Hz Zaehler starten
- ld (HTXWAI),A ; HDLC Wartetimer inaktiv
- ld (CTXWAI),A ; Crosslink Wartetimer inaktiv
- ld (DEICNT),A ; keine Interrupt-Verbietungsstufe
-
- jp mainf_ ; ab ins Hauptprogramm
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : BOOLEAN ishget() "is host get" |
- ; | |
- ; | TRUE - (HL=1, Z=0) Hostterminal an RS232 angeschlossen und |
- ; | Zeichen vom Terminal vorhanden (in RX-FIFO) |
- ; | |
- ; | FALSE - (HL=0, Z=1) Hostterminal nicht an RS232 angeschlossen |
- ; | oder kein Zeichen von Terminal vorhanden (in RX-FIFO) |
- ; | |
- ; | A benutzt, HL Returnwert. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public ishget_
-
- ishget_: call ishost_ ; Hostterminal an RS232 ?
- ret Z ; nein - dann nie frei (FALSE zurueck)
- ld HL,(HORXCC) ; Zeichenzaehler Host-FIFO RX = 0 ?
- ld A,H
- or L
- ret Z ; ja - FALSE zurueck
- ld HL,1 ; nein - TRUE zurueck
- ret
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : hgetc() "host get character" |
- ; | |
- ; | Zeichen von Hostterminal holen, falls angeschlossen und Zeichen da. |
- ; | Falls kein Hostterminal angeschlossen, ASCII Cancel zurueckgeben. |
- ; | Falls kein Zeichen da, warten auf Zeichen. |
- ; | |
- ; | A, DE benutzt, HL Returnwert. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public hgetc_
-
- hgetc_: call ishost_ ; Hostterminal an RS232 ?
- ld A,ACAN ; nein - ASCII CAN = "bisherige Eingabe
- jr Z,hgetc2 ; Loeschen" zurueck
- call ishget_ ; ja - Zeichen vom Hostterminal da ?
- jr Z,hgetc_ ; nein - auf Zeichen warten
- di ; ja - keine Ints (kein Zeigerzugriff)
- ld HL,(HORXCC) ; RX-FIFO Zeichenzaehler - 1
- dec HL
- ld (HORXCC),HL
- ld HL,(HORXOP) ; Output-Zeiger
- ld A,(HL) ; Zeichen aus FIFO holen
- inc HL ; Zeiger auf naechstes Zeichen
- ex DE,HL
- ld HL,HORXFI+HORXFL-1 ; Zeiger > letzte FIFO-Stelle, d.h.
- or A ; "FIFO Wrap Around" ?
- sbc HL,DE
- jr NC,hgetc1 ; nein -
- ld DE,HORXFI ; ja - Zeiger wieder auf FIFO-Anfang
- hgetc1: ld (HORXOP),DE ; Zeiger abspeichern
- ei ; Interrupt wieder frei
- hgetc2: ld L,A ; Zeichen C-like zurueck = return(chr)
- ld H,0
- or A
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : BOOLEAN ishput() "is host put" |
- ; | |
- ; | TRUE - (HL=1, Z=0) Hostterminal an RS232 angeschlossen und es |
- ; | koennen Zeichen gesendet werden an Hostterminal |
- ; | (TX-FIFO leer) |
- ; | |
- ; | FALSE - (HL=0, Z=1) Hostterminal nicht an RS232 angeschlossen |
- ; | oder es duerfen keine Zeichen gesendet werden an |
- ; | Hostterminal (TX-FIFO nicht leer) |
- ; | |
- ; | A benutzt, HL Returnwert. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public ishput_
-
- ishput_: call ishost_ ; Hostterminal an RS232 ?
- ret Z ; nein - immer voll (FALSE zurueck)
- ld HL,(HOTXCC) ; Zeichenzaehler Host-FIFO TX = 0 ?
- ld A,H
- or L
- ret Z ; ja - FALSE zurueck
- ld HL,1 ; nein - TRUE zurueck
- ret
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : VOID hputc(chr) char chr; "host put character" |
- ; | |
- ; | Falls kein Hostterminal an RS232 angeschlossen, Zeichen chr |
- ; | vergessen und Rueckgabe. Sonst Zeichen chr in den Hostterminal- |
- ; | TX-FIFO schreiben, ggf. warten bis Platz im TX-FIFO. |
- ; | Falls TX-FIFO leer war, wird der Interrupt-Zeichensender wieder |
- ; | ange-"kickt". |
- ; | |
- ; | A, HL, DE benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public hputc_
-
- hputc_: call ishost_ ; Hostterminal an RS232 ?
- ret Z ; nein - Zeichen vergessen, Rueckgabe
- ld HL,(HOTXCC) ; ja - TX-FIFO voll ?
- ld DE,HOTXFL
- or A
- sbc HL,DE
- jr NC,hputc_ ; ja - warten bis Platz im TX-FIFO
- ld HL,2 ; nein - Zeichen als C-Parameter vom Stack
- add HL,SP ; holen
- ld A,(HL)
- di ; keine Ints (keine Zeigerzugriffe)
- ld HL,(HOTXCC) ; TX-FIFO Zeichenzaehler + 1
- inc HL
- ld (HOTXCC),HL
- ld HL,(HOTXIP) ; Zeiger auf naechste freie Stelle im TX-FIFO
- ld (HL),A ; Zeichen in TX-FIFO eintragen
- inc HL ; Zeiger auf naechste freie Stelle
- ex DE,HL
- ld HL,HOTXFI+HOTXFL-1 ; Zeiger > letzte FIFO-Stelle, d.h.
- or A ; "FIFO Wrap Around" ?
- sbc HL,DE
- jr NC,hputc1 ; nein -
- ld DE,HOTXFI ; ja - Zeiger wieder auf FIFO-Anfang
- hputc1: ld (HOTXIP),DE ; Zeiger abspeichern
- in A,(SIBCTL) ; SIO Kanal B (RS232) Tx-Buffer leer ?
- bit 2,A
- call NZ,HTXFCO ; ja - naechstes Zeichen aus TX-FIFO
- ; senden (falls sich kein Zeichen
- ; mehr im TX-FIFO befand, wird
- ; hiermit der Interrupt-Sender wieder
- ; ange-"kickt")
- ei ; Interrupts wieder frei
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : VOID kicktx(port) unsigned port; |
- ; | |
- ; | port = 0 : HDLC-Port (Modem) |
- ; | = 1 : Crosslink-Port (RS232) |
- ; | |
- ; | Sender an-"kicken", d.h. wenn Kanal frei ist, Sendezyklus |
- ; | einleiten, wenn Sender am Frameende des letzten Frames, dann |
- ; | Sender mitteilen, dass noch weitere Frames folgen. |
- ; | |
- ; | A, DE, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn Dpar_ ; 1 = Vollduplex an
-
- public kicktx_
-
- kicktx_: push BC ; C Stackframe-Pointer
- push IX ; sichern
- ld HL,6 ; Zeiger auf C-Uebergabe-Parameter
- add HL,SP
- ld A,(HL) ; Parameter LSB holen, Portnummer
- or A ; Kommando fuer Crosslink-Port ?
- jr NZ,kickt3 ; ja -
- ld HL,HTXSTA ; nein - HDLC-Port
- ld A,(HL) ; HDLC-Sender inaktiv ?
- or A
- jr Z,kickt1 ; ja -
- cp 7 ; nein - "in Frame(ende), weitere folgen" ?
- jr C,kickt9 ; ja - TX muss nicht ange-"kickt" werden
- ld (HL),6 ; nein - "in Frameende, weitere folgen" !
- jr Z,kickt9 ; wenn nur "in Frameende" war, reicht das
- ld A,08h ; sonst SIO Kanal A (HDLC) "Send Abort" um
- out (SIACTL),A ; Flagwirklichzueende-Checkframe zu beenden
- jr kickt9 ; das war's
-
- kickt1: ld A,(Dpar_) ; Vollduplexbetrieb ?
- or A
- jr NZ,kickt2 ; ja - keine DCD-Abfrage
- ld A,(SIARR0) ; HDLC-Sender inaktiv, DCD (high, "1") ?
- bit 3,A
- jr Z,kickt2
- inc (HL) ; ja - Sendezyklus einleiten, wenn kein
- jr kickt9 ; DCD mehr anliegt (TX-State = 1/2)
-
- kickt2: ld A,1 ; nein - sofort Sendezyklus einleiten
- call HTXINI ; (TX-State = 3)
- jr kickt9 ; das war's
-
- kickt3: call ishost_ ; Hostterminal angeschlossen ?
- jr NZ,kickt8 ; ja - alle Crosslink-Frames wegwerfen
- ld HL,CTXSTA ; nein - Crosslink-Sender inaktiv ?
- ld A,(HL)
- or A
- jr Z,kickt6 ; ja -
- cp 10 ; nein - (vor-)letztes Zeichen im Sender ?
- jr NC,kickt5 ; ja - direkt neues Frame beginnen
- cp 7 ; nein - TX-State 7 der 9, "Frameende,
- jr Z,kickt4 ; keine weiteren folgen" ?
- cp 9
- jr NZ,kickt9 ; nein - da eh weitere folgen, nix noetig
- kickt4: dec (HL) ; ja - es reicht, dem Sender mitzuteilen,
- jr kickt9 ; "weitere folgen" (7/9 -> 6/8)
-
- kickt5: call CTXSTX ; neues Crosslink-Frame mit ASCII STX
- jr kickt9 ; beginnen
-
- kickt6: ld A,(SIBRR0_) ; Crosslink-Sender inaktiv, Modemstecker DTR
- bit 5,A ; high = 1 = Pin /CTS low, d.h. Kanal frei ?
- jr NZ,kickt7
- inc (HL) ; nein - TX-State = 1/2 "Sendezyklus
- jr kickt9 ; einleiten, wenn Kanal frei wird"
-
- kickt7: ld A,1 ; ja - Crosslink-Sender aktivieren
- call CTXINI ; (TX-State 1 -> 3)
- jr kickt9 ; das war's
-
- kickt8: ld HL,8101h ; Kommando an Crosslink-TX-Buffer :
- call GETSRV ; "alle Frames wegwerfen"
-
- kickt9: pop IX ; C Stackframe-Pointer
- pop BC ; restaurieren
- ret ; das war's endgueltig
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : VOID pushtx() |
- ; | |
- ; | Wenn HDLC-Sender auf Abfall von DCD wartet, sofort auf Sendung |
- ; | gehen (wird gebraucht zur Vermeidung eines Deadlocks bei |
- ; | Umschaltung in den Vollduplex-Betrieb). |
- ; | |
- ; | A, DE, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public pushtx_
-
- pushtx_: push BC ; C Stackframe-Pointer
- push IX ; sichern
- ld HL,HTXSTA ; (HL setzen fuer HTXINI)
- ld A,(HL) ; TX-State = 1 oder 2, "nachdem Port frei
- or A ; wird, senden" ?
- jr Z,pusht1
- cp 3
- call C,HTXINI ; ja - dann Sender sofort hochfahren
- pusht1: pop IX ; C Stackframe-Pointer
- pop BC ; restaurieren
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel B Tx Buffer Empty" - Interruptservice |
- ; | |
- ; | RS232 SIO TX-Buffer leer, entweder (Hostterminal angeschlossen) |
- ; | Zeichen aus Hostterminal-FIFO falls nicht leer senden oder |
- ; | (Crosslink an RS232) Zeichen aus Frame senden, Frameendebehandlung, |
- ; | DLE-Stuffing. |
- ; | |
- ; | |
- ; | Crosslink-Frameformat : |
- ; | |
- ; | +-----+--------- ------+-----+-----+ |
- ; | | STX | info ... | ETX | FCS | |
- ; | +-----+--------- ------+-----+-----+ |
- ; | 02h | 03h 8 Bit Frame Checksumme, |
- ; | | nur ueber info, ohne 1. |
- ; | | DLE bei "Stuffing" |
- ; | | |
- ; | +---> Infobytes, STX in info wird zu DLE STX DLE = 10h |
- ; | ETX " DLE ETX |
- ; | DLE " DLE DLE |
- ; | G8KBB - modified to add KISS code driver |
- ; +---------------------------------------------------------------------+
-
- extrn crlmod_
-
- SIBTBE: ex AF,AF' ; Register sichern
- exx
- push IX
- ld A,28h ; SIO Kanal B (RS232) Reset Tx Int Pending
- out (SIBCTL),A
- call ishost_ ; Hostterminal an RS232 angeschlossen ?
- jp NZ,SIBT11 ; ja -
- ld HL,CTXSTA ; nein - Crosslink-Kanal
- ld A,(HL) ; Crosslink-TX-State :
- sub 5
- jr Z,SIBT4 ; 5: innerhalb Frame
- jp C,SIBT12 ; 0: letztes Zeichen aus SIO -> nix tun
- dec A
- jr Z,SIBT3 ; 6: Frameende, noch weitere, ETX gesendet
- dec A
- jr Z,SIBT3 ; 7: Frameende, keine weiteren, ETX gesendet
- dec A
- jr Z,SIBT2 ; 8: Frameende, noch weitere, FCS gesendet
- dec A
- jr Z,SIBT1 ; 9: Frameende, keine weiteren, FCS gesendet
- dec A
- jr Z,SIBT1 ; 10: Sendungsende, vorletztes Zeichen fertig
- dec A
- jr z,SIBTE1
- ld (HL),5 ; 12: KISS command byte to send
- xor A ; send a '0' ( ie a data ) frame
- jr SIBT9
- SIBTE1: ld (HL),0 ; 11: Sendungsende, letztes Zeichen fertig,
- call CCOFF ; TX inaktiv, Crosslink-"Traeger"
- jp SIBT12 ; abschalten, das war's
-
- SIBT1: inc (HL) ; 9/10 -> 10/11, Zaehler fuer Frameende-
- ld A,(crlmod_) ; if crosslink is KISS, do not send dummy
- or A ; zero as it will confuse things.
- jr NZ,SIBT12
- xor A
- jr SIBT10 ; Feststellung, 00h als Dummy an RS232
-
- SIBT2: call CTXSTX ; Frameende, noch weitere : neues Frame
- jr SIBT12 ; beginnen, das war's
-
- SIBT3: inc (HL) ; Frameende, ETX gesendet : TX-State wie
- inc (HL) ; vorher, aber "FCS gesendet"
- ld A,(CTXFCS) ; Frame-Checksumme
- jr SIBT10 ; aussenden
-
- SIBT4: ld HL,CTXCSA ; kommt jetzt STX/ETX/DLE nach DLE ?
- ld A,(HL)
- or A
- jr Z,SIBT5
- ld (HL),0 ; ja - "nach DLE"-Buffer loeschen
- jr SIBT9 ; und Zeichen aus Buffer aussenden
-
- SIBT5: ld HL,0100h ; nein - Kommando : "naechstes Zeichen aus
- call GETSRV ; TX-Crosslink-Buffer holen" ausfuehren
- ld A,L ; Frame zuende ?
- bit 7,H
- jr Z,SIBT7 ; nein - normales Zeichen
- ld HL,CTXSTA ; ja - TX-State "Frameende, weitere folgen"
- inc (HL)
- bit 0,A ; noch weitere Frames vorhanden ?
- jr Z,SIBT6
- inc (HL) ; nein - TX-State "Frameende, keine weiteren"
- SIBT6: ld A,(crlmod_) ; check for KISS mode
- or A
- jr NZ,SIBT61 ; jump if KISS
- ld A,AETX ; Frame mit ETX beenden
- jr SIBT10
- SIBT61: ld A,FEND ; Send a KISS FRAME END char
- inc (HL)
- inc (HL) ; skip over the checksum state for KISS
- jr SIBT10
-
- SIBT7: ld B,A ; save char in B reg while checking for KISS
- ld A,(crlmod_)
- or A
- ld A,B ; reinstate char
- jr Z,SIBT71 ; jump if crosslink rather than KISS
- cp FEND
- jr NZ,SIBT7a ; check for FEND character within the frame
- ld A,TFEND ; replace FEND with FESC,TFEND
- jr SIBT7b
- SIBT7a: cp FESC ; check for FESC character within frame
- jr NZ,SIBT9 ; go send char if it isn't
- ld A,TFESC ; replace FESC with FESC,TFESC
- SIBT7b: ld (CTXCSA),A
- ld A,FESC
- jr SIBT10
- SIBT71: cp ASTX ; auszusendendes Zeichen STX/ETX/DLE ?
- jr Z,SIBT8
- cp AETX
- jr Z,SIBT8
- cp ADLE
- jr NZ,SIBT9
- SIBT8: ld (CTXCSA),A ; ja - entsprechendes Zeichen merken
- ld A,ADLE ; und DLE aussenden
- jr SIBT10
-
- SIBT9: ld C,A ; nein - Zeichen merken
- ld HL,CTXFCS ; Checksumme := Checksumme + Zeichen
- add A,(HL)
- ld (HL),A
- ld A,C ; Zeichen restaurieren und senden
-
- SIBT10: out (SIBDAT),A ; Zeichen an SIO ausgeben
- jr SIBT12 ; das war's
-
- SIBT11: call HTXFCO ; Zeichen aus Hostterminal-Buffer an RS232
-
- SIBT12: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel B External Status Change" - Interruptservice |
- ; | |
- ; | RS232 DCD Wechsel |
- ; | DCD ist das Crosslink/Hostterminal-Signal. Ein Wechsel bedeutet |
- ; | Umschaltung von Hostterminal auf Crosslink oder umgekehrt. Es |
- ; | werden alle Buffer, FIFO's und Variable fuer Crosslink und |
- ; | Hostterminal initialisiert. Noch nicht verarbeitete Inhalte |
- ; | werden weggeworfen. Ggf. wird der Crosslink-"Vorlauftraeger" |
- ; | abgeschaltet. |
- ; | |
- ; | SIO Pin /CTS = RS232 Modemstecker DTR Wechsel |
- ; | Dies ist das Crosslink-Kanal-"DCD". Ein Wechsel bedeutet den |
- ; | Wechsel von einem freien auf einen belegten Kanal oder umgekehrt. |
- ; | Geschieht ein Wechsel von besetzt auf frei und der Sender wartete |
- ; | auf freien Kanal, dann wird entsprechend die Sendesequenz |
- ; | aktiviert ("Vorlauftraeger" oder "Async"-WAIT"). |
- ; | Geschieht ein Wechsel von frei auf besetzt und der Sender befand |
- ; | sich im "Async"-WAIT Warten oder im "Vorlauftraeger", dann wird |
- ; | die Sendesequenz abgebrochen und wieder auf Warten auf freien |
- ; | Kanal gesetzt, ggf. wird der Crosslink-"Vorlauftraeger" |
- ; | abgeschaltet. |
- ; | |
- ; | 1200 Hz SIO Pin SYNC Flanken |
- ; | Dies ist der grundlegende Timer-Interrupt. Hieraus wird der |
- ; | System-10-msec-Takt abgeleitet. Der Systemtimer wird aufgerufen |
- ; | und die Senderwartevariablen werden verwaltet. Bei Ablauf wird |
- ; | entsprechend der Sendesequenz verfahren. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn timer_ ; C Systemtimer (10 msec)
- extrn hststs_ ; host mode status register
- extrn hstmod_ ; host mode flag
- extrn hotout_ ; host mode timeout counter
-
- SIBESC: ex AF,AF' ; Register sichern
- exx
- push IX
- in A,(SIBCTL) ; Status SIO Kanal B (RS232) holen
- ld B,A ; und merken
- ld A,10H ; Reset External/Status Interrupts
- out (SIBCTL),A
- ld HL,SIBRR0_
- ld A,(HL) ; alter Status
- ld (HL),B ; neuen Status merken
- xor B
- ld C,A ; C = was hat sich geaendert
- bit 3,C ; Abfrage DCD-Wechsel-Interrupt
- jr Z,SIBE1
-
- ;
- ; DCD hat sich geaendert
- ;
- push BC ; Status/Statusaenderung merken
- call HOINIT ; Hostterminal-FIFO's loeschen,
- ; Crosslink-"Traeger" aus
- ld BC,8101h ; aktive Crosslink-TX-Buffer in
- call PUTSRV ; "Gesendet"-Liste einhaengen
- ld HL,8101h ; aktive Crosslink-RX-Buffer
- call GETSRV ; auf den Muell werfen
- xor A ; Crosslink RX/TX Variable resetten
- ld (CRXSTA),A
- ld (CTXSTA),A
- ld (CTXWAI),A
- pop BC ; Status/Statusaenderung restaurieren
-
- SIBE1: bit 5,C ; Abfrage CTS-Wechsel-Interrupt
- jr Z,SIBE5
-
- ;
- ; Pin /CTS = Modemstecker DTR hat sich geaendert
- ; (Crosslink-"Traeger" Input)
- ;
- push BC ; Status/Statusaenderung merken
- bit 3,B ; check to see if crosslink or host
- jr Z,SIBE20 ; if crosslink, go do old code
- ld A,(hstmod_) ; else check if host mode enabled
- or A
- jr NZ,SIBE2H ; If so, go handle host mode CTS change
- SIBE20: ld HL,CTXSTA
- ld A,(HL) ; Pin /CTS low = Modemstecker DTR high =
- bit 5,B ; Crosslink-Kanal frei zur Sendung ?
- jr Z,SIBE2 ; nein - ging also von frei auf besetzt
- or A ; ja - Crosslink-TX inaktiv ?
- jr Z,SIBE4 ; ja - nix weiter tun
- cp 3 ; nein - auf "Kanal frei" wartend ?
- jr NC,SIBE4 ; nein - TX muss nicht aktiviert werden
- call CTXINI ; ja - Crosslink-Sendesequenz aktivieren
- jr SIBE4
-
- SIBE2H: ld HL,hststs_ ; point to state parameter for host mode
- ld A,(HL) ; switch on state.....
- or A
- jr Z,SIBEH0 ; state 0
- dec A
- jr Z,SIBEH1 ; state 1
- dec A
- jr Z,SIBEH2 ; state 2
- dec A
- jr Z,SIBEH3 ; state 3
- dec A
- jr NZ,SIBE4 ; state 4 - drop thru rather than jump
- bit 5,B ; 4:
- jr NZ,SIBE4 ; check if DTR true - jump if not
- ld (HL),3 ; set to state 3
- call dropdcd_ ; drop DCD
- ld A,20
- ld (hotout_),A ; timeout 20 seconds
- jr SIBE4
- SIBEH0: bit 5,B ; 0:
- jr NZ,SIBE4 ; check if DTR true - jump if not
- ld (HL),5 ; set to state 5
- call raisedcd_ ; raise DCD
- jr SIBE4
- SIBEH1: bit 5,B ; 1:
- jr NZ,SIBE4 ; check if DTR true - jump if not
- ld (HL),2 ; set to state 2
- jr SIBE4
- SIBEH2: bit 5,B ; 2:
- jr Z,SIBE4 ; check if DTR true - jump if it is
- ld (HL),7 ; set to state 7
- jr SIBE4
- SIBEH3: bit 5,B ; 3:
- jr Z,SIBE4 ; check if DTR true - jump if it is
- ld (HL),0 ; set to state 0
- jr SIBE4
-
- SIBE2: sub 3 ; Crosslink-Kanal frei -> besetzt,
- jr Z,SIBE3 ; "Async"-WAIT Wartezustand (State 3)
- dec A ; oder Crosslink-"Vorlauftraeger" (State 4) ?
- jr NZ,SIBE4 ; nein - nix weiter tun
- SIBE3: ld (CTXWAI),A ; ja - Wartezaehler inaktivieren ( = 0),
- dec (HL) ; TX-Wartezustand wieder auf Zustand
- dec (HL) ; vor Warten/"Vorlauftraeger"
- bit 1,(HL) ; war es "Vorlauftraeger" (4-2=2) ?
- call NZ,CCOFF ; ja - diesen abschalten
-
- SIBE4: pop BC ; Status/Statusaenderung restaurieren
-
-
- SIBE5: bit 4,C ; Abfrage SYNC-Flanken-Interrupt
- jr Z,SIBE9
-
- ;
- ; Flanke am Pin SYNC = 1200 Hz Interrupt
- ;
- ld HL,CTXWAI ; Crosslink TX-Wartezaehler inaktiv ?
- ld A,(HL)
- or A
- jr Z,SIBE7 ; ja -
- dec (HL) ; nein - abgelaufen ?
- jr NZ,SIBE7 ; nein -
- ld HL,CTXSTA ; ja - war es "Vorlauftraeger" (State 4) ?
- ld A,(HL)
- cp 4
- jr Z,SIBE6
- inc (HL) ; nein - war "Async"-WAIT, ab jetzt 2,5 msec
- call CTXPRE ; Crosslink-"Vorlauftraeger" (State 4)
- jr SIBE7
- SIBE6: call CTXSTX ; ja - Frame beginnen
-
- SIBE7: ld HL,TICDIV ; 1200 Hz -> 10 msec Teiler abgelaufen ?
- inc (HL)
- ld A,(HL)
- cp 12
- jr C,SIBE9 ; nein - dann war's das
-
- ;
- ; alle 10 msec :
- ;
- ld (HL),0 ; ja - Teiler neu aktivieren
- call timer_ ; 10 msec Ticker im Hauptprogamm
- ld HL,HTXWAI ; HDLC-TX-Wartezaehler aktiv ?
- ld A,(HL)
- or A
- jr Z,SIBE9 ; nein - dann war's das
- dec (HL) ; ja - abgelaufen ?
- jr NZ,SIBE9 ; nein - dann war's das
- ld HL,HTXSTA ; ja - in TXDELAY ?
- ld A,(HL)
- cp 4
- jr Z,SIBE8 ; ja - Frame beginnen
- dec A ; nein - TX-Statezaehler fuer HTXINI
- dec A ; korrigieren und Sender
- call HTXINI ; hochfahren
- jr SIBE9
-
- SIBE8: inc (HL)
- call HTXSOF ; ja - Frame beginnen
-
- SIBE9: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel B Rx Character Available" - Interruptservice |
- ; | |
- ; | RS232 SIO RX Zeichen da, entweder (Hostterminal angeschlossen) |
- ; | Zeichen in den Hostterminal-FIFO schreiben falls nicht voll, oder |
- ; | (Crosslink an RS232) Zeichen in Crosslink-Buffer schreiben, |
- ; | Frameendebehandlung, DLE-Stuffing. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- SIBRCA: ex AF,AF' ; Register sichern
- exx
- push IX
- in A,(SIBDAT) ; Zeichen von RS232 holen
- ld C,A
- call ishost_ ; Hostterminal angeschlossen ?
- jp NZ,SIBR8 ; ja -
-
- ;
- ; Crosslink an RS232
- ;
- ld HL,CRXSTA ; nein - Crosslink
- ld A,(HL) ; Crosslink-RX-State :
- or A
- jr Z,SIBR1 ; 0: RX inaktiv
- dec A
- jr Z,SIBR3 ; 1: RX aktiv, innerhalb Frame
- dec A
- jr Z,SIBR5 ; 2: RX aktiv, letztes Zeichen war DLE
- dec A
- jr nz,SIBR11 ; 4: KISS ignore command byte
- ld (HL),0 ; 3: Frameende, Checksumme kommt, (3 -> 0)
- ld A,(CRXFCS) ; RX Checksumme ok ?
- cp C
- ld BC,8100h ; (Befehl "Crosslink-RX-Buffer in RX-Liste")
- jr Z,SIBR7 ; ja - Frame ok, in RX-Liste einhaengen
- inc C ; (Befehl "Crosslink-RX-Buffer auf Muell)
- ld HL,(l2stats_+82)
- inc HL ; bump checksum error l2stats[10][1]
- ld (l2stats_+82),HL
- jr SIBR7 ; nein - Framebuffer auf den Muell werfen
-
- SIBR1: ld A,(crlmod_) ; check if in KISS mode
- or A
- ld A,C ; RX inaktiv,
- jr Z,SIBR1a ; if not KISS, jump
- cp FEND ; if KISS, check for FEND character at start
- jp NZ,SIBR10
- ld (HL),4 ; then go to mode 4 to ignore command byte
- jr SIBR2
- SIBR1a: cp ASTX ; Zeichen = Frameanfang (STX) ?
- jp NZ,SIBR10 ; nein - dann war's das
- inc (HL) ; ja - RX-State "RX innerhalb Frame" (1)
- SIBR2: xor A ; RX-Checksumme loeschen
- ld (CRXFCS),A
- ld BC,8101h ; neuen Crosslink-RX-Buffer beginnen
- jr SIBR7 ; das war's
-
- SIBR3: ld A,(crlmod_) ; check for KISS mode
- or A
- ld A,C ; RX aktiv, innerhalb Frame,
- jr Z,SIBR3a ; jump for non KISS
- cp FEND
- jr Z,SIBR40 ; end of frame detected
- cp FESC
- jr Z,SIBR4 ; KISS frame escape character
- jr SIBR6
- SIBR3a: cp ASTX ; Zeichen = Frameanfang (STX) ?
- jr Z,SIBR2 ; ja - RX resetten, neues Frame
- cp ADLE ; Zeichen DLE ?
- jr Z,SIBR4 ; ja - RX-State "letztes Zeichen DLE" (2)
- cp AETX ; nein - Zeichen = Frameende (ETX) ?
- jr NZ,SIBR6 ; nein - normales Info-Zeichen
- inc (HL) ; ja - RX-State "Checksumme kommt" (3)
- SIBR4: inc (HL)
- jr SIBR10 ; das war's
-
- SIBR40: ld (hl),0 ; KISS end of frame
- ld BC,8100h ; no checksum - just valid data !
- jr SIBR7 ; so go to it !
-
- SIBR5: ld A,(crlmod_)
- or A
- jr Z,SIBR5b ; jump if not KISS mode
- ld A,C ; get received character to replace
- cp TFESC ; replace shifted ESC by ESC
- jr NZ,SIBR5a
- ld C,FESC
- jr SIBR5b
- SIBR5a: cp TFEND ; replace shifted END by END
- jr NZ,SIBR5b
- ld C,FEND
- SIBR5b: dec (HL) ; letztes Zeichen war DLE, naechstes Zeichen
- ; (STX/ETX/DLE) ist Info, RX-State 2 -> 1
- SIBR6: ld HL,CRXFCS ; Info-Zeichen
- ld A,(HL) ; auf Checksumme
- add A,C ; addieren
- ld (HL),A
- ld B,0001h ; und in Crosslink-RX-Buffer
- SIBR7: call PUTSRV ; Crosslink-RX-Buffer-Verwaltung
- jr SIBR10 ; das war's
-
- SIBR11: ld A,C ; KISS - ignore command byte
- cp FEND ; unless it is an END byte
- jr Z,SIBR2
- ld (HL),1
- jr SIBR10
-
- ;
- ; Hostterminal an RS232
- ;
- SIBR8: ld HL,HORXFL ; noch Platz im RX-Hostterminal-FIFO, d.h.
- ld DE,(HORXCC) ; Zeichenzaehler + 1 <= FIFO-Laenge ?
- inc DE
- or A
- sbc HL,DE
- jr C,SIBR10 ; nein - Zeichen vergessen
- ld (HORXCC),DE ; ja - Zeichenzaehler + 1 abspeichern
- ld HL,(HORXIP) ; Zeiger auf naechste freie Stelle
- ld (HL),C ; Zeichen in den FIFO einschreiben
- inc HL ; Zeiger auf naechste Stelle
- ex DE,HL
- ld HL,HORXFI+HORXFL-1 ; Zeiger > letzte FIFO-Stelle, d.h.
- or A ; "FIFO Wrap Around" ?
- sbc HL,DE
- jr NC,SIBR9 ; nein -
- ld DE,HORXFI ; ja - Zeiger auf FIFO-Anfang
- SIBR9: ld (HORXIP),DE ; Zeiger abspeichern
-
- SIBR10: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel B Special Receive Condition" - Interruptservice |
- ; | |
- ; | RS232-Fehlerbedingung ruecksetzen. Nicht auswerten - Fehler ist |
- ; | Fehler und im Kommunikationsablauf passiert nix (Crosslink-Frame |
- ; | ist eh kaputt, und wen interessierts am Hostterminal, w a s |
- ; | passiert ist). |
- ; | |
- ; +---------------------------------------------------------------------+
-
- SIBSRC: push AF ; benutztes Register sichern
- push HL
- ld A,1
- out (SIBCTL), A ; Read register 1 ( special recv codes )
- in A,(SIBCTL)
- push AF ; preserve AF whilst resetting error flag
- ld A,30h ; SIO Kanal B (RS232) Error Reset
- out (SIBCTL),A ; (Achselzucken. Kann ja nix passieren.)
- pop AF ; reinstate register 1
- bit 6,A ; check for framing error
- jr NZ,SIBSR1 ; go bump count if there is
- bit 5,A ; check for overrun error
- jr Z,SIBSR0 ; skip on if no error
- SIBSR1: ld HL,(l2stats_+66)
- inc HL ; bump error count l2stats[8][1]
- ld (l2stats_+66),HL
- SIBSR0: pop HL
- pop AF ; benutztes Register restaurieren
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel A Tx Buffer Empty" - Interruptservice |
- ; | |
- ; | HDLC SIO TX-Buffer leer, naechstes Zeichen aus HDLC-TX-Framebuffer |
- ; | holen und senden, wenn innerhalb Frame. Bei Frameende ohne Zeichen- |
- ; | ausgabe in den Underrun/EoM-Interrupt laufen lassen. |
- ; | Nach einem Underrun/EoM-Interrupt entweder neues Frame beginnen |
- ; | (es sind noch weitere vorhanden) oder Dummyframe zur Feststellung |
- ; | des Endes des vorherigen Frames beginnen (keine weiteren mehr |
- ; | vorhanden). Nachdem ueber das Dummyframe Ende (Flag von vorherigem |
- ; | Frame hat SIO verlassen) des vorherigen Frames festgestellt wurde, |
- ; | Sender abschalten. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn cwstate_, cwkick
- extrn xFpar_ ; 1 = Flags in Pausen senden, 0 sonst
-
- SIATBE: ex AF,AF' ; Register sichern
- exx
- push IX
- ld A,28h ; SIO Kanal A (HDLC) Reset TX Int Pending
- out (SIACTL),A
- ld HL,HTXSTA ; HDLC-TX innerhalb Frame Datenbytes ?
- ld A,(HL)
- sub 5
- jr NZ,SIAT1 ; nein -
- ld L,A ; ja - Zeichen aus HDLC-TX-Framebuffer
- ld H,A ; (HL=0) holen in HL
- call GETSRV
- ld A,L ; Zeichen in A
- bit 7,H ; Frame zueende ?
- jr Z,SIAT4 ; nein - Zeichen an HDLC-Port ausgeben
- ld HL,HTXSTA ; ja - TX-State "Frameende, weitere folgen"
- inc (HL)
- bit 0,A ; folgen noch weitere Frames ?
- jr Z,SIAT5 ; ja - dann war's das (ab in Underrum/EoM)
- inc (HL) ; nein - TX-State "Frameende, keine weiteren"
- jr SIAT5 ; das war's dann (ab in Underrun/EoM)
-
- SIAT1: dec A ; TX-State 6 "Frameende, weitere folgen" ?
- jr NZ,SIAT2
- dec (HL) ; ja - TX-State 6 -> 5, "Innerhalb Frame",
- call HTXSOF ; neues Frame beginnen
- jr SIAT5 ; das war's
-
- SIAT2: dec A ; nein - TX-State :
- jr Z,SIAT3 ; 7: 1. CRC-Byte gesendet, TX-State 7 -> 8,
- ; Dummyframe zur Feststellung des
- ; sicheren Endes des vorherigen Frames
- ; mit 00h beginnen
- dec A
- jr Z,SIAT3 ; 8: CRC verlaesst SIO, TX-State 8 -> 9,
- ; 00h an Dummyframe
- dec A
- jr Z,SIAT3 ; 9: Flag verlaesst SIO, TX-State 9 -> 10,
- ; 00h an Dummyframe
- dec A
- jr NZ,SIAT5 ; <5: -> ignorieren (Dummyframeende)
- ; cwstarts here
- ld A,(cwstate_) ; if CW state is '-1', it is waiting to start
- inc A ; so if it is, and if we are in state 10, then
- jr NZ, SIAT2b ; call cwkick in order to send cwid tacked on
- SIAT2c: call cwkick ; to the end of the current transmission.
- jr SIAT5
- SIAT2b: inc A ; check also if calibrate is waiting to start
- jr Z,SIAT2c ; if so, then go kick it into action
- xor A
- ; end of cw code link
- ld (HL),A ; 10: Flag komplett gesendet,
- ; TX-State 10 -> 0, Sender abschalten
- ld A,5 ; Pin /RTS high = Ptt aus, TX Disable
- out (SIACTL),A
- ld HL,SIAWR5
- res 1,(HL)
- ld A,(xFpar_) ; ( Flags in Pausen ein ? )
- or A
- jr NZ,SIAT2a ; ( ja - SIO-TX eingeschaltet lassen )
- res 3,(HL) ; ( nein - SIO-TX ausschalten )
- SIAT2a: ld A,(HL)
- out (SIACTL),A ; neuen Sendemodus merken
- ld A,(Dpar_) ; Vollduplex an ?
- or A
- call Z,HRXRES ; nein - HDLC-RX resetten = einschalten
- jr SIAT5 ; das war's
-
- SIAT3: inc (HL) ; naechster TX-State
- SIAT4: out (SIADAT),A ; Zeichen an SIO
- SIAT5: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel A External Status Change" - Interruptservice |
- ; | |
- ; | Falls Sender aus und Frameabort empfangen, HDLC-RX resetten, gerade |
- ; | aktives Frame auf den Muell. |
- ; | |
- ; | Falls HDLC-TX-Underrun, Frame Abort senden und Frame noch einmal |
- ; | senden. |
- ; | |
- ; | Falls DCD von an auf aus gewechselt hat und sich Sender in Zustand |
- ; | "nach DCD aus leite Sendesequenz oder WAIT-Warten ein" befindet, |
- ; | die naechste Sequenz entsprechend einleiten. |
- ; | |
- ; | Falls DCD von aus auf an gewechselt hat und sich der Sender in |
- ; | WAIT-Warte-Sequenz befindet, dann WAIT-Warten abbrechen und nach |
- ; | naechstem Wechsel an auf aus wieder neu von vorne. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- SIAESC: ex AF,AF' ; Register sichern
- exx
- push IX
- ld A,10h ; SIO Kanal A (HDLC) Reset External/Status
- out (SIACTL),A ; Interrupts
- in A,(SIACTL) ; neuen Status holen
- ld B,A ; B = neuer Status
- ld HL,SIARR0
- ld A,(HL) ; alten Status holen
- ld (HL),B ; neuen Status merken
- xor B ; C = was hat sich geaendert ?
- ld C,A
- ld HL,HTXSTA ; TX innerhalb Frame Datenbytes ?
- ld A,(HL)
- cp 5
- jr NZ,SIAE1 ; nein -
- bit 6,B ; ja - TX-Underrun ?
- jr Z,SIAE1 ; nein - war wohl DCD-Wechsel
- push AF
- push BC
- push HL
- ld A,08h ; ja - Programm nicht schnell genug, Frame
- out (SIACTL),A ; "ordentlich" mit Abort beenden,
- ld (HL),6 ; TX-State "letztes Byte aus Frame
- ; gesendet, weitere Frames folgen",
- ld HL,8000h ; aktuellen HDLC-TX-Framebuffer
- call GETSRV ; "rewinden" = Frame gleich noch
- ld HL,(l2stats_+72)
- inc HL ; increment underrun count l2stats[9][0]
- ld (l2stats_+72),HL
- pop HL ; einmal probieren
- pop BC
- pop AF
-
- SIAE1: bit 3,C ; hat DCD gewechselt ?
- jr Z,SIAE4 ; nein - dann kann es RX Abort sein
- push BC ; Status sichern
- bit 3,B ; DCD angegangen ?
- jr NZ,SIAE2 ; ja -
- or A ; nein - DCD ausgegangen - Sender inaktiv ?
- jr Z,SIAE3 ; ja - DCD-Wechsel ignorieren
- cp 3 ; nein - TX-State 1 oder 2,
- ; "TX-Sequenz bei DCD aus einleiten" ?
- jr NC,SIAE3 ; nein - DCD-Wechsel ignorieren
- call HTXINI ; ja - Sendesequenz einleiten
- jr SIAE3
-
- SIAE2: cp 3 ; DCD angegangen, waehrend "WAIT abwarten" ?
- jr NZ,SIAE3 ; nein - DCD-Wechsel ignorieren
- ld A,(Dpar_) ; ja - Vollduplex an ?
- or A
- jr NZ,SIAE3 ; ja - DCD ignorieren
- ld (HL),1 ; nein - Spiel von vorn, TX-State "nachdem
- ; DCD aus WAIT-Sequenz einleiten",
- xor A ; Wartezaehler inaktivieren
- ld (HTXWAI),A
- SIAE3: pop BC ; Status restaurieren
-
- SIAE4: bit 7,C ; hat HDLC RX ein Abort empfangen ?
- call NZ,HRXRE1 ; ja - eingeschalteten Empfaenger resetten
-
- SIAE5: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel A Rx Character Available" - Interruptservice |
- ; | |
- ; | Zeichen aus HDLC-Kanal ist angekommen. Ist es das erste Zeichen |
- ; | eines neuen Frames, dann neuen Framebuffer anlegen, Zeichen merken. |
- ; | Sonst Zeichen merken und vorheriges Zeichen in den Framebuffer |
- ; | schreiben (vorheriges Zeichen, damit nicht vor dem Anzeigen des |
- ; | Frameendes CRC-Byte in den Buffer geraet). Bei zu langem Frame |
- ; | RX resetten und Frame wegwerfen. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- SIARCA: ex AF,AF' ; Register sichern
- exx
- push IX
- in A,(SIADAT) ; Zeichen holen SIO Kanal A (HDLC)
- ld HL,HRXSTA ; RX-State = 1, d.h. "Innerhalb Frame" ?
- inc (HL)
- dec (HL)
- jr NZ,SIAR1
- inc (HL) ; nein - "Ausserhalb" -> "Innerhalb Frame"
- ld (HRXLCH),A ; Zeichen im 1-Zeichen-FIFO merken
- ld BC,8001h ; neuer HDLC-RX-Buffer
- call PUTSRV
- jr SIAR2 ; das war's
-
- SIAR1: ld HL,HRXLCH ; ja - "Innerhalb Frame",
- ld C,(HL) ; altes Zeichen gueltige Info
- ld (HL),A ; neues altes Zeichen
- ld B,0000h ; gueltiges Zeichen in den
- call PUTSRV ; HDLC-RX-Buffer schreiben
- dec L ; Fehler dabei, d.h. Frame zu lang ?
- call Z,HRXRES ; ja -> HDLC-RX Reset, Frame wegwerfen
-
- ld A,ADC_CH2 ; start S meter reading
- out (ADC),A
-
- SIAR2: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "SIO channel A Special Receive Condition" - Interruptservice |
- ; | |
- ; | Bei richtigem Frameende (CRC ok, kein Overrun, volle Bytes) wird |
- ; | Frame in die HDLC-RX-Frameliste eingehaengt, sonst wird das |
- ; | aktuelle Frame weggeworden. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- SIASRC: ex AF,AF' ; Register sichern
- exx
- push IX
- ld A,1 ; SIO Kanal A (HDLC) RR1 = Fehlerstatus holen
- out (SIACTL),A
- in A,(SIACTL)
- ld B,A ; Fehlerstatus sichern
- ld A,30h ; SIO Kanal A (HDLC) Error Reset
- out (SIACTL),A
- ;
- in A,(ADC) ; read S meter
- ld (sig_level_),A ; put here for l1put() to read
- ld A,ADC_CH1 ; load 'start convert channel 1 command'
- out (ADC),A ; into the ADC chip
- ;
- ld A,B ; Fehlerstatus restaurieren
- ld BC,8001h ; "aktiven HDLC-RX-Framebuffer auf den Muell"
- bit 5,A ; RX Overrun ?
- jr Z, SIAS0 ; no, skip on to SIAS0
- ld HL,(l2stats_+(8*8)) ; increment port 0 rx overrun count
- inc HL
- ld (l2stats_+(8*8)),HL
- jr SIAS1
- ; jr NZ,SIAS1 ; ja - Frame wegwerfen
- SIAS0:
- bit 7,A ; End of Frame ?
- jr Z,SIAS2 ; nein - nix tun (war "All Sent")
- bit 6,A ; CRC Fehler ?
- jr NZ,SIAS3 ; invalid, bump error count
- ; jr NZ,SIAS1 ; ja - Frame wegwerfen
- and 0Eh ; nein - war Frame modulo 8 Bit und letztes
- ; gueltiges Zeichen vorletztes
- ; Zeichen (letztes in Buffer) ?
- cp 6
- jr Z, SIAS00 ; yes, frame OK, so skip over
- SIAS3: ld A,(SIARR0)
- bit 3,A
- jr Z,SIAS1
- ld HL,(l2stats_+80) ; no - bump crc error count
- inc HL
- ld (l2stats_+80),HL
- jr SIAS1
- ; jr NZ,SIAS1 ; nein - Frame wegwerfen
- SIAS00: dec C ; ja - Frame ok, in HDLC-RX-Liste haengen
- SIAS1: call HRXNEW ; Bufferkommando ausfuehren, Frame zuende
-
- SIAS2: pop IX ; Register restaurieren
- exx
- ex AF,AF'
- ei ; Interrupts wieder erlauben
- reti ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "Hostterminal TX FIFO character out" |
- ; | |
- ; | Wenn noch Zeichen im Hostterminal-TX-FIFO, dann Zeichen aus diesem |
- ; | FIFO holen und an RS232 ausgeben. |
- ; | |
- ; | A, DE, HL bentzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- HTXFCO: ld HL,(HOTXCC) ; Zeichen in TX-FIFO ?
- ld A,H
- or L
- ret Z ; nein - nix tun
- dec HL ; ja - TX-FIFO Zeichenzaehler - 1
- ld (HOTXCC),HL
- ld HL,(HOTXOP) ; Zeiger auf Zeichen
- ld A,(HL) ; Zeichen holen
- out (SIBDAT),A ; an SIO Kanal B (RS232) ausgeben
- inc HL ; Zeiger auf naechstes Zeichen
- ex DE,HL
- ld HL,HOTXFI+HOTXFL-1 ; Zeiger > letzte FIFO-Stelle, d.h.
- or A ; "FIFO Wrap Around" ?
- sbc HL,DE
- jr NC,HTXFC1 ; nein -
- ld DE,HOTXFI ; ja - Zeiger wieder auf FIFO-Anfang
- HTXFC1: ld (HOTXOP),DE ; Zeiger abspeichern
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | CTXINI "Crosslink TX initialize" |
- ; | Sender initialisieren, ggf. mit "Async"-WAIT. |
- ; | A = 1 -> Sender mit "Async"-WAIT initialiseren |
- ; | A = 2 -> Sender ohne "Async"-WAIT initialisieren, gleich zu |
- ; | CTXPRE |
- ; | |
- ; | CTXPRE "Crosslink TX preset" |
- ; | 2,5 msec Crosslink-"Vorlauftraeger" setzen. |
- ; | |
- ; | CTXSTX "Crosslink TX start of text" |
- ; | Crosslinkframe beginnen mit ASCII Start of Text. |
- ; | |
- ; | A, DE, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public raisedcd_
- extrn sentdata_
-
- CTXINI: inc A ; naechster Sendestatus 1/2 -> 3/4
- inc A
- ld HL,CTXSTA
- ld (HL),A
- cp 4 ; erstes Frame zu digipeatendes Frame ?
- jr Z,CTXPRE ; nein - kein "Async"-WAIT
- call random_ ; ja - "Async"-WAIT beachten
- and 1Fh ; 3 < A < 32 = 2,5 msec ... 25 msec
- or 03h ; (1200Hz/3 ... 1200Hz/32)
- ld (CTXWAI),A
- ret
-
- CTXPRE: call raisedcd_
- ld A,3 ; 2,5 msec (1200Hz/3)
- ld (CTXWAI),A
- ret ; das war's
-
- CTXSTX: xor A
- ld (CTXFCS),A ; Sende-Framechecksumme initialisieren
- ld (CTXCSA),A ; "kein STX/ETX/DLE innerhalb Frame"
- ld A,1
- ld (sentdata_+1),A ; port flush - mark data as sent
- ld A,(crlmod_) ; check for KISS mode
- or A
- jr Z,CTXST0 ; jump if not KISS
- ld (HL),12 ; else change to state 12
- ld A,FEND ; and send a frame start character
- jr CTXST1
- CTXST0: ld (HL),5 ; Sendestatus "Innerhalb Crosslink-Frame"
- ld A,ASTX ; Frame beginnt mit ASCII STX,
- CTXST1: out (SIBDAT),A ; Interruptsender an-"kicken"
- ret ; das war's
-
-
- raisedcd_: ld A,5 ; 2,5 msec Crosslink-"Vorlauftraeger" setzen
- out (SIBCTL),A
- ld HL,SIBWR5
- res 1,(HL) ; "/RTS high after TX empty" -> /RTS high
- ld A,(HL) ; = Modemstecker CTS low
- out (SIBCTL),A ; = Crosslink-"Traeger" ein
- ret
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | HOINIT "Host initialize" |
- ; | Alle Hostterminal-FIFO's (RX und TX) resetten, Crosslink- |
- ; | "Traeger" ausschalten. |
- ; | |
- ; | CCOFF "Crosslink carrier off" |
- ; | Crosslink-"Traeger" ausschalten = Pin /RTS low = Modemstecker |
- ; | CTS high. |
- ; | |
- ; | A, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public dropdcd_
-
- HOINIT: ld HL,0
- ld (HORXCC),HL ; alle Hostterminal-FIFO's resetten
- ld (HOTXCC),HL
- ld HL,HORXFI
- ld (HORXIP),HL
- ld (HORXOP),HL
- ld HL,HOTXFI
- ld (HOTXIP),HL
- ld (HOTXOP),HL
- xor A
- ld (hststs_),A
-
- dropdcd_:
- CCOFF: ld A,5 ; SIO Kanal B (RS232)
- out (SIBCTL),A
- ld HL,SIBWR5 ; Pin /RTS low = Modemstecker CTS high
- set 1,(HL) ; = Crosslink-"Traeger aus"
- ld A,(HL)
- out (SIBCTL),A
- ret
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | HTXINI "HDLC TX initialize" |
- ; | Sender initialisieren, ggf. mit WAIT. |
- ; | A = 1 -> Sender mit WAIT initialiseren |
- ; | A = 2 -> Sender ohne WAIT initialisieren, gleich zu HTXKUP |
- ; | |
- ; | HTXKUP "HDLC TX key up" |
- ; | HDLC RX abschalten, Sender einschalten, PTT ein, TXDELAY starten. |
- ; | |
- ; | HTXSOF "HDLC TX start of frame" |
- ; | Zeichen aus TX-Framebuffer holen und mit diesem Zeichen neues |
- ; | Frame beginnen. |
- ; | |
- ; | A, DE, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn Wpar_ ; WAIT-Parameter in 10 msec
- extrn Ppar_ ; P-Persistenz-Wert
- extrn Tpar_ ; TXDELAY-Parameter in 10 msec
-
- HTXINI: inc A ; naechster Sendestatus 1/2 -> 3/4
- inc A
- ld (HL),A
- cp 4 ; erstes Frame zu digipeatendes Frame ?
- jr Z,HTXKUP ; ja - kein WAIT beachten
- ld A,(Dpar_) ; nein - Vollduplexbetrieb ?
- or A
- jr NZ,HTXIN1 ; ja - Sender sofort hochfahren
- push HL ; nein - (Zeiger auf HTXSTA sichern)
- call random_ ; Zufallszahl <= P-Persistenz-Wert ?
- ld A,(Ppar_)
- cp L
- pop HL ; (Zeiger auf HTXSTA wiedereinsetzen)
- jr NC,HTXIN1 ; ja - Sender hochfahren
- ld A,(Wpar_) ; nein - Slottime abwarten
- ld (HTXWAI),A
- or A ; falls Slottime = 0 gleich weiter
- ret NZ
-
- HTXIN1: inc (HL) ; TX-State 3 -> 4
- HTXKUP: ld A,(Dpar_) ; Vollduplexbetrieb ?
- or A
- jr NZ,HTXKU0
- ld A,3 ; nein - "RX disable" = HDLC-Empfaenger
- out (SIACTL),A ; abschalten
- ld A,(SIAIW3)
- res 0,A
- out (SIACTL),A
- HTXKU0: ld A,5 ; "TX enable", Pin /RTS low =
- out (SIACTL),A ; HDLC-Sender einschalten, PTT ein
- ld A,1
- ld (sentdata_),A ; port flush - mark data as sent
- ld HL,SIAWR5
- set 3,(HL)
- set 1,(HL)
- ld A,(HL)
- out (SIACTL),A ; (geaenderten Sende-Modus merken)
- ld A,(Tpar_) ; TXDELAY in Wartezaehler
- ld (HTXWAI),A
- or A ; TXDELAY-Parameter > 0 ?
- ret NZ ; ja - TXDELAY abwarten
- ld HL,HTXSTA ; nein - kein TXDELAY (TX State = 5)
- inc (HL)
- HTXSOF: ld HL,0 ; "Zeichen holen aus HDLC-TX-Framebuffer"
- call GETSRV ; Zeichen holen in L
- ld A,80h ; "Reset HDLC TX CRC Generator"
- out (SIACTL),A
- ld A,L ; Zeichen ausgeben, erstes Zeichen in Frame,
- out (SIADAT),A ; dadurch Interrupt-Sender ange-"kickt"
- ld A,0C0h ; "Reset HDLC TX Underrun/EoM Latch",
- out (SIACTL),A ; damit Frameende erkannt werden kann
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | "get service" |
- ; | |
- ; | l1get-Aufruf mit HL als Parameter, Ergebnis in HL zurueck. |
- ; | Auch von innerhalb Interruptroutinen aufrufbar, da Interrupt- |
- ; | verbietungsstufe beibehalten wird, o h n e ggf. ein EI bei |
- ; | l1get-Aufruf auszuloesen. |
- ; | |
- ; | l1get ist die TX-Buffer-Verwaltung, Zeichen holen, Kommandos zur |
- ; | Bufferbehandlung, Meldungen zum Bufferzustand. |
- ; | |
- ; | A, DE benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn l1get_ ; C TX-Buffer-Verwaltung
-
- GETSRV: push HL ; Aufrufparameter fuer C-Routine l1get
- ld HL,DEICNT ; zu fruehes EI durch l1get verhindern
- inc (HL)
- call l1get_ ; C-Routine l1get ausfuehren
- ex DE,HL ; Ergebnis von l1get in DE
- ld HL,DEICNT ; wieder alte Interrupt-Verbietungsstufe
- dec (HL)
- ex DE,HL ; Ergebnis von l1get in HL
- pop DE ; Stack korrigieren (l1get Parameter)
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | HRXRES "HDLC RX Reset" |
- ; | HDLC RX neu anfangen lassen, SIO und Buffer initialisieren. |
- ; | |
- ; | HRXRE1 |
- ; | Wie HRXRES, aber SIO in Ruhe lassen, nur Buffer initialisieren. |
- ; | |
- ; | HRXNEW "HDLC RX New" |
- ; | Wie PUTSRV, am Frameende. Restzeichen aus SIO entfernen, |
- ; | Empfangsstatus initialiseren fuer naechstes Frame. |
- ; | |
- ; | PUTSRV "put service" |
- ; | l1put-Aufruf mit BC als Parameter, Ergebnis in HL zurueck. |
- ; | Auch von innerhalb Interruptroutinen aufrufbar, da Interrupt- |
- ; | verbietungsstufe beibehalten wird, o h n e ggf. ein EI bei |
- ; | l1get-Aufruf auszuloesen. |
- ; | |
- ; | l1put ist die RX-Buffer-Verwaltung, Zeichen schreiben, Kommandos |
- ; | zur Bufferbehandlung, Meldungen zum Bufferzustand. |
- ; | |
- ; | A, BC, DE benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- extrn l1put_ ; C RX-Buffer-Verwaltung
- public HRXRES
-
- HRXRES: ld A,03h ; SIO Kanal A, RX CRC enable, CRC enable,
- out (SIACTL),A ; Hunt Phase (initiales WR3)
- ld A,(SIAIW3)
- out (SIACTL),A
- HRXRE1: ld BC,8001H ; aktiven RX-Framebuffer auf den Muell,
- ; wenn nicht leer, sonst neuen beginnen
- HRXNEW: in A,(SIADAT) ; Zeichen aus HDLC-Kanal holen und vergessen
- xor A ; HDLC RX-State : "RX ausserhalb Frame"
- ld (HRXSTA),A
- PUTSRV: push BC ; Aufrufparameter fuer l1put
- ld HL,DEICNT ; zu fruehes EI durch l1put verhindern
- inc (HL)
- call l1put_ ; C-Routine l1put ausfuehren
- ex DE,HL ; l1put-Returnwert merken
- ld HL,DEICNT ; wieder alte Interrupt-Verbietungsstufe
- dec (HL)
- ex DE,HL ; l1put-Returnwert restaurieren
- pop BC ; Stack korrigieren (l1put Parameter)
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : BOOLEAN iscd(port) unsigned port; "is carrier detect" |
- ; | |
- ; | Test, ob Port (Kanal) mit Nummer port belegt ist (d.h. nicht |
- ; | gesendet werden darf). |
- ; | |
- ; | port = 0 : HDLC Modemport |
- ; | = 1 : RS232 Crosslinkport |
- ; | |
- ; | |
- ; | TRUE - (HL=1, Z=0) Kanal ist belegt |
- ; | |
- ; | FALSE - (HL=0, Z=1) Kanal ist frei (oder Vollduplex-HDLC) |
- ; | |
- ; | |
- ; | A benutzt, HL Returnwert. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public iscd_
-
- iscd_: ld HL,2 ; Portnummer als 16-Bit-C-Parameter vom
- add HL,SP ; Stack holen
- ld A,(HL)
- ld HL,0 ; default Returnwert FALSE
- dec A ; Crosslink-Port (RS232), d.h. 1 ?
- jr NZ,iscd2 ; nein -
-
- ;
- ; Crosslink-Port
- ;
- ld A,(SIBRR0_) ; ja - SIO Kanal B Status holen
- and 00100000b ; Pin /CTS low = Modem DTR high ("1") ?
- jr NZ,iscd1
- inc A ; nein - H=1, Z=0, TRUE zurueck
- ld L,A ; (Kanal belegt)
- ret
- iscd1: xor A ; ja - H=0, Z=1, FALSE zurueck
- ret ; (Kanal frei)
-
- ;
- ; HDLC-Port
- ;
- iscd2: ld A,(Dpar_) ; Vollduplexbetrieb ?
- dec A
- ret Z ; ja - Z = 1, A = 0, HL = 0, FALSE
- ld A,(SIARR0) ; SIO Kanal A Status holen
- bit 3,A ; SIO Kanal A DCD an ?
- ret Z ; nein - FALSE zurueck (Kanal frei)
- inc HL ; ja - TRUE zurueck (Kanal belegt)
- ret
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : BOOLEAN ishost() "is host terminal" |
- ; | |
- ; | Rueckgabe : TRUE, HL = 1, Z = 0 - Hostterminal an RS232 |
- ; | FALSE, HL = 0, Z = 1 - Crosslink an RS232 |
- ; | |
- ; | A benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public ishost_
-
- ishost_: ld HL,0 ; Rueckgabe-Preset FALSE
- ld A,(SIBRR0_) ; DCD an RS232 (SIO Kanal B) ?
- and 00001000b
- ret Z ; nein - FALSE zurueck (Crosslink)
- inc HL ; ja - TRUE zurueck (Hostterminal)
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : char *minmem() "minimum memory" |
- ; | |
- ; | Niedrigste nutzbare RAM-Freispeicherstelle in HL zurueck, |
- ; | Test auf 0 fuer C-Kompatibilitaet. |
- ; | |
- ; | A benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public minmem_
-
- ; extrn fremem_ ; erste Speicherstelle Freispeicher
- extrn Fremem_
-
- minmem_:
- ; ld HL,fremem_ ; niedrigste nutzbare RAM-Freispeicherstelle
- ld HL,(Fremem_) ; ** COMPILER DIFFERENCE !!!! ** - Aztec C
- ld A,H ; als C-Funktionswert zurueck
- or L
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : char *maxmem() "maximum memory" |
- ; | |
- ; | Hoechste nutzbare RAM-Freispeicherstelle in HL zurueck, |
- ; | Test auf 0 fuer C-Kompatibilitaet. |
- ; | |
- ; | A benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public maxmem_
-
- maxmem_: ld HL,(RAMTOP) ; hoechste nutzbare RAM-Freispeicherstelle
- ld A,H ; als C-Funktionswert zurueck
- or L
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : VOID DIinc() "disable interrupt increment" |
- ; | |
- ; | Interrupts verbieten, Verbietungsstufe erhoehen. |
- ; | |
- ; | |
- ; | HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public DIinc_
-
- DIinc_: di ; Interrupts verbieten
- ld HL,DEICNT ; auf die naechste Verbietungsstufe
- inc (HL)
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : VOID decEI() "decrement enable interrupt" |
- ; | |
- ; | Verbietungsstufe erniedrigen, wenn dann gleich 0, Interrupts |
- ; | wieder erlauben. |
- ; | |
- ; | HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public decEI_
-
- decEI_: ld HL,DEICNT ; Verbietungsstufe - 1
- dec (HL) ; Erlaubnis erreicht ?
- ret NZ ; nein - dann war's das
- ei ; ja - Interrupts wieder erlauben
- ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : BOOLEAN CONled(on) BOOLEAN on; "CONNECT-LED" |
- ; | |
- ; | Ein- oder Ausschalten der CONNECT-LED. |
- ; | |
- ; | Parameter : on = TRUE, 1 -> LED anschalten |
- ; | on = FALSE, 0 -> LED ausschalten |
- ; | |
- ; | A, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- ; public CONled_
-
- ;CONled_: di ; Int's duerfen nicht dazwischenfunken
- ; ld A,5 ; /DTR-Pin = LED-Ausgang wird ueber SIO
- ; out (SIBCTL),A ; Register 5 angesteuert
- ; ld HL,2 ; Zeiger auf Parameter
- ; add HL,SP
- ; ld A,(HL) ; Parameter low Byte holen
- ; rrca ; Bit 0 -> Bit 7
- ; xor 80h ; Bit 0-6 loeschen, Bit 7 invertieren
- ; ld HL,SIBWR5
- ; res 7,(HL) ; SIO B /DTR Pin entsprechend Parameter
- ; or (HL) ; (on = TRUE -> Pin /DTR low -> LED ein)
- ; ld (HL),A
- ; out (SIBCTL),A ; selbiges auch merken
- ; ei ; Interrupts wieder erlauben
- ; ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : BOOLEAN STAled(on) BOOLEAN on; "STATUS-LED" |
- ; | |
- ; | Ein- oder Ausschalten der STATUS-LED. |
- ; | |
- ; | Parameter : on = TRUE, 1 -> LED anschalten |
- ; | on = FALSE, 0 -> LED ausschalten |
- ; | |
- ; | A, HL benutzt. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- ; public STAled_
-
- ;STAled_: di ; Int's duerfen nicht dazwischenfunken
- ; ld A,5 ; /DTR-Pin = LED-Ausgang wird ueber SIO
- ; out (SIACTL),A ; Register 5 angesteuert
- ; ld HL,2 ; Zeiger auf Parameter
- ; add HL,SP
- ; ld A,(HL) ; Parameter low Byte holen
- ; rrca ; Bit 0 -> Bit 7
- ; xor 80h ; Bit 0-6 loeschen, Bit 7 invertieren
- ; ld HL,SIAWR5
- ; res 7,(HL) ; SIO A /DTR Pin entsprechend Parameter
- ; or (HL) ; (on = TRUE -> Pin /DTR low -> LED ein)
- ; ld (HL),A
- ; out (SIACTL),A ; selbiges auch merken
- ; ei ; Interrupts wieder erlauben
- ; ret ; das war's
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : VOID srand() |
- ; | |
- ; | Zufallszahlengenerator initialisieren. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public srand_
-
- srand_: ld A,R ; 0 <= A <=127 (oder 128 <= A <= 255)
- ld L,A ; URAND = A
- ld H,0
- ld (URAND),HL
- ret
-
-
-
-
-
- ; +---------------------------------------------------------------------+
- ; | |
- ; | C : unsigned random() |
- ; | |
- ; | 8-Bit Quasi-Zufallszahl (0..255) holen in A und HL. |
- ; | |
- ; +---------------------------------------------------------------------+
-
- public random_
-
- random_: ld HL,(URAND) ; URAND rueckgekoppelt linksschieben
- ld A,H ; (Zweck: Gleichverteilung random())
- and 01100000b
- jp PO,rand1
- scf
- rand1: adc HL,HL
- ld (URAND),HL
- ld A,R ; 0 <= A <=127 (oder 128 <= A <= 255)
- add A,A ; 0 <= A <= 254, gerade
- inc A ; 1 <= A <= 255, ungerade
- xor L ; 0 <= A <= 255
- ld L,A ; HL = A
- ld H,0 ; (nur LSB signifikant)
- ret ; das war's
-
- end